You may be familiar with the most common HTML tags like p, a, and img, but what about progress or details? HTML is a lot more expressive than you might have realized, and the following tags pack plenty of functionality.
Find out what you can use each of these hidden gems for, and why they’re so useful.
HTML has supported multimedia elements—images, video, audio—for many decades, but the latter two required browser plugins like Adobe’s Flash to work. Thankfully, HTML5 brought native audio and video elements to the web, and implementations have been improving ever since.
Today’s audio element is a clean, minimal player with the controls you’d expect: a play/pause button, timing details, and an interactive progress bar. You can even style this player, to some extent, making it a full-width element, for example.
The widget will vary from browser to browser. Chrome, for example, includes a volume and mute control. But, across browsers, this tag provides a trivial way of supporting audio playback, with programmable features to extend its behavior if you want.
HTML is a declarative markup language, concerned with the meaning of content rather than how it appears in a browser. For looks, there’s CSS, but even that language is a responsive one that can render very differently from one device to the next.
If you’re working on a component that demands pixel precision, however, the canvas element is for you. Using canvas, you can write text on the page in an exact font and draw graphics with certainty.
This doesn’t mean you should reach for canvas all the time, though; it’s not a good replacement for the real content on your pages. But if you’re building a game or a highly-tailored interface for a narrow use, canvas can be an effective means of doing so.
Right-click on a canvas element in your browser, and you’ll get an option to save it as an image.
This obscure element can extend certain types of inputs by offering a set of suggested values to choose from. For example, when paired with a text input, you’ll get autocomplete without any code, just by declaring the set of valid options:
You can then connect an input element with this list using its id:
It doesn’t stop there, though; datalist works with other types of elements. It pairs well with color inputs, where browsers can offer a palette of preferred colors:
datalist support varies across browsers, so make sure you test it carefully. Fortunately, this element should degrade gracefully when unsupported.
The details element is possibly the clearest example of a highly-functional HTML element that many people overlook or simply don’t know about. It can be highly effective when used on its own, and can even replace JavaScript code to produce a modern component when paired with CSS.
details creates a disclosure widget, a part of your content that the reader can toggle to display or hide. These are great for things like quizzes, supplemental information, and can even approximate more complex tabbed interfaces.
In its simplest form, this tag is easy to use:
Hello, world!
You can also pair it with a summary element to customize the legend at the top of the widget:
...
Content goes here...
This element has been around for a while, and its simplicity may lead you to think it’s not that useful, but that’s far from the case. You can use the mark element to call attention to a specific piece of text that is otherwise semantically identical to the text that surrounds it.
The default browser style usually renders the mark element with a yellow background:
This nods towards a highlighter pen style, which implies calling out a range of text as particularly important or relevant to a given context.
One of the best uses for mark is to highlight search results. You can also use it to call out content that has been commented on or highlight differences between one piece of text and another.
My favorite elements are those that do a lot with little. They take existing needs that have been fulfilled with countless JavaScript implementations and satisfy them with standard, consistent, reliable HTML.
progress is a case in point. This tag produces a styleable, scriptable progress bar to represent the completion status of a task:
You can use progress with a floating point value between 0 and 1:
Or you can provide a maximum and a value relative to it:
Without any value at all, you should find that your browser animates the progress bar to indicate ongoing activity without a known status.
The picture tag is just a modern equivalent of img, right? Not quite: picture has a lot more to offer, most of it under the guise of responsive design.
The results might look just the same as an img, but this tag’s all about how you arrive at the destination. Using picture, you can select an image according to:
Format, meaning you can support a wider range of devices.
File size, so you can improve performance and save users’ bandwidth.
Layout, so you can tailor your design to screen size.
This is all achieved with a structure that allows for several image options instead of one:
Each source element provides details of a candidate image, plus attributes that describe when it should be used. The img element is still used, but here it’s a fallback in case an appropriate source cannot be determined.
Using picture does involve a bit more work than a single img, but it’s a lot easier than trying to maintain separate entire websites for each use.
I’ll end on an advanced tag that relies on JavaScript, but can transform the process of working with dynamic content significantly.
As its name suggests, a template element defines markup that you can use to create new markup easily. By default, template elements won’t show up, but they are part of the DOM, and you can use them to create elements that will appear.
Without template, adding content to the DOM requires either a lot of code (using createElement, createTextNode, appendChild, and similar methods) or a lot of string processing, with innerHTML, which can be insecure if you’re not careful. Using template, you can define a chunk of markup like this:
You can then replicate that content with a simple call to clone and add it to the DOM using importNode. This is much less work than the alternative: